﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public interface INormalItem
{
    void OnRecycle();
}
public class UIObjCacheProcess<T> where T:MonoBehaviour,INormalItem
{
    private Transform cacheRoot, viewRoot;
    private T prefab;
    private List<T> cacheList;
    private List<T> useItems;
    public void ResetViewRoot(Transform viewRoot)
    {
        this.viewRoot = viewRoot;
    }
    public T Find(Predicate<T> match)
    {
       return   useItems.Find(match);
    }
    public UIObjCacheProcess(Transform cacheRoot, Transform viewRoot,T prefab,int poolInitNum = 0)
    {
        this.prefab = prefab;
        this.cacheRoot = cacheRoot;
        this.viewRoot = viewRoot;
        cacheList = new List<T>();
        useItems = new List<T>();
        CreatePool(poolInitNum);
    }
    private void CreatePool(int poolNum)
    {
        for (int i = 0; i < poolNum; i++)
        {
            var temp= CreateItem(cacheRoot);
            useItems.Add(temp);
            Recycle(temp);
        }
    }
    public T Spawn()
    {
        T temp = null;
        if (cacheList.Count > 0)
        {
            temp = cacheList[0];
            
            temp.transform.SetParent(viewRoot);
            temp.gameObject.SetActive(true);
            useItems.Add(temp);

            cacheList.RemoveAt(0);
        }
        else
        {
            temp = CreateItem(viewRoot);
            useItems.Add(temp);
        }
        return temp;
    }

    private T CreateItem(Transform root)
    {
        var newObj = GameObject.Instantiate<T>(prefab, root);
        newObj.gameObject.SetActive(true);
        newObj.transform.localPosition = Vector3.zero;
        newObj.transform.localScale = Vector3.one;
        newObj.transform.localEulerAngles = Vector3.zero;
        return newObj;
    }

    public bool Recycle(T unUse)
    {
        if (useItems.Contains(unUse))
        {
            unUse.gameObject.SetActive(false);
            unUse.transform.SetParent(cacheRoot);
            unUse.OnRecycle();
            useItems.Remove(unUse);
            cacheList.Add(unUse);
            return true;
        }
        else
        {
            return false;
        }
    }
    
    public void RecycleAll()
    {
        //对列表移除需要倒叙 以避免正序指针向前移位的情况
        for (int i = useItems.Count - 1; i >= 0; i--)
        {
            Recycle(useItems[i]);
        }
    }

    public void Destroy()
    {  
    }
}
